<?php

require_once (SRC_DIR . '/framework/DB/DBConnection.php');
require_once (SRC_DIR . '/framework/DB/DBResult.php');
require_once (SRC_DIR . '/framework/DB/MySQLiDBConnection.php');
require_once (SRC_DIR . '/framework/DB/MySQLiDBResult.php');
require_once (SRC_DIR . '/framework/DB/MySQLiDBResultIterator.php');


class TestMySQLiDBConnection extends UnitTestCase	{
	
	protected $testTableName = '___unittesting';
	
	protected $dbSettings = array(
		'schema' => 'seraph_test',
		'host' => 'localhost',
		'user' => 'seraph_test',
		'pass' => 'password'
	);
	
	public function setUp()	{
		$mysqliConfig = $this->dbSettings;
		//delete the test table
		$mysql = new mysqli($mysqliConfig['host'], $mysqliConfig['user'], $mysqliConfig['pass'], $mysqliConfig['schema']);
		$dropTableSQL = 'DROP TABLE IF EXISTS ' . $this->testTableName . ';';
		$mysql->query($dropTableSQL);
	}
	
	public function TearDown()	{
		$mysqliConfig = $this->dbSettings;
		//delete the test table
		$mysql = new mysqli($mysqliConfig['host'], $mysqliConfig['user'], $mysqliConfig['pass'], $mysqliConfig['schema']);
		$dropTableSQL = 'DROP TABLE IF EXISTS ' . $this->testTableName . ';';
		$mysql->query($dropTableSQL);
	}
	
	public function testFailedConnection()	{
		$mysqliConfig = $this->dbSettings;
		
		//for negative test, use the correct server just to prevent having to wait for timeout
		$this->expectError();
		$mySQLiBad = new MySQLiDBConnection($mysqliConfig['host'], 'wibble', 'wibble', 'wibble');
		
		$failedConnection = $mySQLiBad->doConnect();
		
		$this->assertFalse($failedConnection);
		$this->assertTrue($mySQLiBad->getConnectError());
	}
	
	public function testSuccessConnection()	{
		$mysqliConfig = $this->dbSettings;
		$mysqli = new MySQLiDBConnection($mysqliConfig['host'], $mysqliConfig['user'], $mysqliConfig['pass'], $mysqliConfig['schema']);

		$success = $mysqli->doConnect();
		$this->assertTrue($success);
		$this->assertNull($mysqli->getConnectError());
		$this->assertIsA($mysqli->getConnection(), 'mysqli');
	}
	
	public function testQuerys()	{
		$createTableSQLFormat = '
CREATE TABLE `%1$s` (
  `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  `test_col` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`)
)
ENGINE = InnoDB;
';
		$createTableSQL = sprintf(
			$createTableSQLFormat,
			$this->testTableName
		);
		
		$mysqliConfig = $this->dbSettings;
		$db = new MySQLiDBConnection($mysqliConfig['host'], $mysqliConfig['user'], $mysqliConfig['pass'], $mysqliConfig['schema']);
		
		$res = $db->query($createTableSQL);
		
		$this->assertTrue($res->isSuccess(), 'create table sql failed');
		
		$insertSQLFormat = '
INSERT INTO %1$s
(test_col)
VALUES
("wibble");
';
		$insertSQL = sprintf($insertSQLFormat, $this->testTableName);
		$res = $db->query($insertSQL);
		
		$this->assertTrue($res->isSuccess());
		$this->assertEqual(1, $res->getAffectedRowsCount());
		$this->assertEqual(1, $db->getLastInsertID());
		
		$res = $db->query($insertSQL);
		
		$this->assertTrue($res->isSuccess());
		$this->assertEqual(1, $res->getAffectedRowsCount());
		$this->assertEqual(2, $db->getLastInsertID());
		

	}
	
	public function testSelectSQLGeneration()	{
		$mysqliConfig = $this->dbSettings;
		$db = new MySQLiDBConnection($mysqliConfig['host'], $mysqliConfig['user'], $mysqliConfig['pass'], $mysqliConfig['schema']);
		
		$expectedNoWhereSQL = '
SELECT *
FROM `a_table`

;';
		
		$expectedWithWhereSQL = "
SELECT *
FROM `a_table`
WHERE `a` = 'kaboom' AND `b` = 'whoosh'
;";
		
		$withWhereSQL = $db->generateSelectSQLStatement('a_table', array('a' => 'kaboom', 'b' => 'whoosh'));
		$this->assertEqual($expectedWithWhereSQL, $withWhereSQL);
		
		
		//sql injection testing
		$expectedWithInjectionSQL = "
SELECT *
FROM `a_ta\';DROP TABLE pants;\'ble`
WHERE `\"evil\"` = '\'bob\\\" OR 1=1'
;";
		
		$withInjectionSQL = $db->generateSelectSQLStatement("a_ta';DROP TABLE pants;'ble", array('"evil"' => "'bob\" OR 1=1"));
		$this->assertEqual($expectedWithInjectionSQL, $withInjectionSQL);
		
	}
	

	public function testGetTableNames()	{
		$mysqliConfig = $this->dbSettings;
		$db = new MySQLiDBConnection($mysqliConfig['host'], $mysqliConfig['user'], $mysqliConfig['pass'], $mysqliConfig['schema']);
		
		$this->assertTrue(is_array($db->getTableNames()));
		
		//can't be totally sure of the tables, so just check that the test table does not exist
		$this->assertFalse(in_array($this->testTableName, $db->getTableNames()));
		
		//add the test table
		$createTableSQLFormat = '
CREATE TABLE `%1$s` (
  `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  `test_col` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`)
)
ENGINE = InnoDB;
';
		
		$createTableSQL = sprintf(
			$createTableSQLFormat,
			$this->testTableName
		);
		
		$db->query($createTableSQL);
		
		//check that the table now exists
		$this->assertTrue(in_array($this->testTableName, $db->getTableNames()));
	}
}
?>